package com.lc.projects.unit.thread.part03.test1;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Phaser;

//并发阶段任务的执行 Phaser
public class Test5 {
	public static void main(String[] args) {
		Phaser phaser = new Phaser(3);
		FileSearch system = new FileSearch("C:\\Program Files", "exe", phaser);
		FileSearch program = new FileSearch("D:\\BOOK", "pdf", phaser);
		FileSearch document = new FileSearch("C:\\Users\\user\\Documents", "sql", phaser);

		Thread t1 = new Thread(system, "system");
		Thread t2 = new Thread(program, "program");
		Thread t3 = new Thread(document, "document");
		t1.start();
		t2.start();
		t3.start();

		try {
			t1.join();
			t2.join();
			t3.join();

		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		System.out.println("Terminated:" + phaser.isTerminated());
	}
}

class FileSearch implements Runnable {

	private String initPath;
	private String end;
	private List<String> results;

	private Phaser phaser;

	public FileSearch(String initPath, String end, Phaser phaser) {
		super();
		this.initPath = initPath;
		this.end = end;
		this.phaser = phaser;
		results = new ArrayList<>();
	}

	private void directoryProcess(File file) {
		File[] list = file.listFiles();
		if (list != null) {
			for (int i = 0; i < list.length; i++) {
				if (list[i].isDirectory()) {
					directoryProcess(list[i]);
				} else {
					fileProcess(list[i]);
				}
			}
		}
	}

	private void fileProcess(File file) {
		if (file.getName().endsWith(end)) {
			results.add(file.getAbsolutePath());
		}
	}

	private void filterResults() {
		List<String> newResults = new ArrayList<>();
		long currentDate = new Date().getTime();
		for (int i = 0; i < results.size(); i++) {
			File file = new File(results.get(i));
			long fileDate = file.lastModified();
			if (currentDate - fileDate > 0 ) {
				// TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)
				newResults.add(file.getAbsolutePath());
			}
		}

		results = newResults;
	}

	private boolean checkResults() {
		if (results.isEmpty()) {
			System.out.println(Thread.currentThread().getName() + " Phase:" + phaser.getPhase() + " Empty");
			phaser.arriveAndDeregister();
			return false;
		} else {
			System.out.println(
					Thread.currentThread().getName() + " Phase:" + phaser.getPhase() + " Results:" + results.size());
			phaser.arriveAndAwaitAdvance();
			return true;
		}
	}

	private void showInfo() {
		for (int i = 0; i < results.size(); i++) {
			File file = new File(results.get(i));
			System.out.println(Thread.currentThread().getName() + " " + file.getAbsolutePath());
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		phaser.arriveAndAwaitAdvance();
	}

	@Override
	public void run() {
		phaser.arriveAndAwaitAdvance();
		System.out.println(Thread.currentThread().getName() + " Starting.");
		File file = new File(initPath);
		if (file.isDirectory()) {
			directoryProcess(file);
		}

		if (!checkResults()) {
			return;
		}

		filterResults();

		if (!checkResults()) {
			return;
		}

		showInfo();
		System.out.println(Thread.currentThread().getName() + " Work completed.");
		phaser.arriveAndDeregister();

	}

}
